/**
 * AnimatedSprite class is sprite that use several images and can be animated.
 * To reset and start animated sprite, simply use start()
 * To control animation speed, adjust the interval attribute.
 * To control animation frame sequence, use addSprite().
 */

function AnimatedSprite(data) {
	this.init(data);
	this.isFinished = false;
	this.currentSprite = null;
	this.currentFrame = 0;
	this.lastTick = 0;
}

AnimatedSprite.prototype = {
	start: function() {
		this.isFinished = false;
		this.currentFrame = 0;
	},
	init: function(data) {
		if (data) {

			this.isLooping = data.isLooping;
			if (typeof this.isLooping != "boolean")
				this.isLooping = true;

			this.image = data.image;
			this.frameWidth = data.frameWidth;
			this.frameHeight = data.frameHeight || this.frameWidth;
			this.framesPerRow = Math.floor(this.image.width / this.frameWidth),
			this.sprites = [];
			this.interval = data.interval;

			this.left = data.left;
			this.top = data.top;
			this.width = data.width || this.frameWidth;
			this.height = data.height || this.frameHeight;

			this.onCompleted = data.onCompleted;
		}

	},
	// an image can contain many different sprites,
	// using this method to add a new sprite (or a frame sequence)
	// with two required parameters (startFrame and frameCount)
	addSprite: function(data) {
		this.sprites[data.name] = {
			// name : data.name,
			startFrame: data.startFrame || 0,
			framesCount: data.framesCount || 1,

			marginLeft: data.marginLeft || 0,
			marginTop: data.marginTop || 0,
			marginRight: data.marginRight || 0,
			marginBottom: data.marginBottom || 0
		};

		this.currentSprite = this.currentSprite || this.sprites[data.name];
	},
	// change the currentSprite
	setSprite: function(name) {
		if (this.currentSprite != this.sprites[name]) {
			this.currentSprite = this.sprites[name];
			this.currentFrame = 0;
		}
	},
	update: function() {
		if (this.isFinished)
			return;

		var newTick = (new Date()).getTime();

		if (newTick - this.lastTick >= this.interval) {
			// loop throught the frame sequence and change the currentFrame
			this.currentFrame++;
			// reached the last frame
			if (this.currentFrame == this.currentSprite.framesCount) {
				// if this is a circulate sprite, reset the currentFrame
				if (this.isLooping)
					this.currentFrame = 0;
				else {
					// otherwise, raise the completed event
					this.isFinished = true;
					if (this.onCompleted)
						this.onCompleted();
				}
			}

			this.lastTick = newTick;
		}

	},

	draw: function(context, mapOffsetX, mapOffsetY) {

		if (!mapOffsetX)
			mapOffsetX = 1;
		if (!mapOffsetY)
			mapOffsetY = 1;

		if (this.isFinished)
			return;
		var realIndex = this.currentSprite.startFrame + this.currentFrame;
		var row = Math.floor(realIndex / this.framesPerRow);
		var col = realIndex % this.framesPerRow;
		
		var sx = col * this.frameWidth + this.currentSprite.marginLeft;
		var sy = row * this.frameHeight + this.currentSprite.marginTop;
		var sw = this.frameWidth - this.currentSprite.marginRight - this.currentSprite.marginLeft;
		var sh = this.frameHeight - this.currentSprite.marginBottom - this.currentSprite.marginTop;

		context.drawImage(this.image, sx, sy, sw, sh, this.left - mapOffsetX, this.top - mapOffsetY, (4 * sw) / 5, (4 * sh) / 5);
	}
}